package com.hd.controller.app;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hd.controller.base.BaseController;
import com.hd.entity.activiti.BaseVO;
import com.hd.entity.activiti.ProcessInstanceEntity;
import com.hd.entity.activiti.UserTask;
import com.hd.entity.sys.User;
import com.hd.service.activiti.ActivitiService;
import com.hd.service.activiti.ProcessInstanceEntityService;
import com.hd.service.activiti.ProcessTypeService;
import com.hd.service.sys.UserService;
import com.hd.util.JsonUtil;
import com.hd.util.StringUtils;
import com.hd.util.result.Page;
import com.hd.util.result.PageInfo;
import com.hd.util.result.Result;
@Controller
@RequestMapping("/app")
public class AppProcessController extends BaseController {
	private static final Logger log=LoggerFactory.getLogger(AppProcessController.class);
	public static Integer PROCESSTYPE_FLOW=1;
	@Autowired
	private ActivitiService activitiService;
	@Autowired
	private UserService userService;
	@Autowired
	private ProcessInstanceEntityService processInstanceEntityService;
	@Autowired
	private ProcessTypeService processTypeService;
	@Autowired
	private HistoryService historyService;
	@Autowired
	private TaskService taskService;
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private RuntimeService runtimeService;
	/**
	 * 查询待办
	 */
	@RequestMapping(value = "/getTodoTask", method =  RequestMethod.POST)
	@ResponseBody
	public Object todoTask(@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
			@RequestParam(value = "rows", required = false, defaultValue = "10") Integer rows, String userId
			,@RequestParam(value="name",required = false)String name)
			throws Exception {
		if (page < 1) {
			page = 1;
		}
		User user = userService.get(userId);
		Page<BaseVO> p = new Page<BaseVO>(page, rows);
		Map<String,Object>condition=new HashMap<String,Object>();
		if(StringUtils.isNotNull(name)) {
			condition.put("param", name);
		}
		p.setCondition(condition);
		List<BaseVO> taskList = this.activitiService.findTodoTask(user, p);
		List<Object> jsonList = new ArrayList<Object>();
		if(taskList.size()>0){
			for (BaseVO base : taskList) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("businessType", base.getBusinessType_());
				map.put("businessKey", base.getBusinessKey_());
				map.put("user_name", base.getUserName_());
				map.put("title", base.getTitle_());
				map.put("taskId", base.getTask().getId());
				map.put("taskName", base.getTask().getName());
				map.put("createTime", base.getTask().getCreateTime());
				String assign = base.getTask().getAssignee();
				if (assign != null) {
					User u = this.userService.get(assign);
					assign = u.getName();
				}
				String owner = base.getTask().getOwner();
				if (owner != null) {
					User u = this.userService.get(owner);
					owner = u.getName();
				}
	
				map.put("assign", assign);
				map.put("owner", owner);
				map.put("taskDefinitionKey", base.getTask().getTaskDefinitionKey());
				map.put("processInstanceId", base.getProcessInstance().getId());
				map.put("processDefinitionId", base.getProcessInstance().getProcessDefinitionId());
				map.put("processDefinitionKey", base.getProcessDefinition().getKey()); // 任务跳转用
				map.put("supended", base.getProcessInstance().isSuspended());
				map.put("version", base.getProcessDefinition().getVersion());
				map.put("status", base.getStatus_());
				// 任务执行人
				String assigneeOrCandidateUser = (String) activitiService
						.findTodoTaskAssigneeOrCandidateUsers(base.getProcessInstance().getId()).get("userNames");
				map.put("assigneeOrCandidateUser", assigneeOrCandidateUser);
				jsonList.add(map);
			}
		}
		PageInfo pp = new PageInfo(page, rows);
		pp.setTotal(p.getTotal());
		pp.setRows(jsonList);
		return pp;
	}

	/**
	 * 已办流程
	 * 
	 * @param page
	 * @param rows
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/getMyComplete")
	@ResponseBody
	public Object myfindFinishedProcessInstances(@RequestParam(value = "page", required = false,defaultValue = "1") Integer page,
			@RequestParam(value = "rows", required = false,defaultValue = "10") Integer rows, String userId
			,@RequestParam(value="name",required = false)String name) throws Exception {
		Page<BaseVO> p = new Page<BaseVO>(page, rows);
		List<Object> jsonList = new ArrayList<Object>();
		Map<String,Object>condition=new HashMap<String,Object>();
		if(StringUtils.isNotNull(name)) {
			condition.put("param", name);
		}
		p.setCondition(condition);
		User user = new User();
		user.setId(userId);
		List<BaseVO> processList = this.activitiService.findFinishedTaskInstances(user, p);
		if (processList.size() > 0) {
			for (BaseVO base : processList) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("processInstanceId", base.getProcessInstanceId_());
				// 查询业务类型
				ProcessInstanceEntity processInstance = processInstanceEntityService.get(base.getProcessInstanceId_());
				map.put("businessType", processInstance.getBusinessType());
				map.put("businessKey", processInstance.getBusinessKey());
				map.put("user_name", processInstance.getUserName());
				map.put("title", processInstance.getTitle());
				map.put("startTime", base.getStartTime_());
				map.put("endTime", base.getEndTime_());
				map.put("deleteReason", base.getDeleteReason_());
				map.put("version", base.getVersion_());
				map.put("taskId", base.getTaskId());
				map.put("taskName", base.getTaskName());
				jsonList.add(map);
			}
		}
		PageInfo info = new PageInfo(page, rows);
		info.setTotal(p.getTotal());
		info.setRows(jsonList);
		return info;
	}
	
	/**
	 * 我的申请
	 * @param page
	 * @param rows
	 * @param userId
	 * @param name
	 * @return
	 */
	@RequestMapping(value = "/getMyApproval")
	@ResponseBody
	public Object getMyApproval(@RequestParam(value = "page", required = false,defaultValue = "1") Integer page,
			@RequestParam(value = "rows", required = false,defaultValue = "10") Integer rows, String userId
			,@RequestParam(value="name",required = false)String name) {
		PageInfo info=new PageInfo(page,rows);
		Map<String,Object>condition=new HashMap<String,Object>();
		condition.put("userid", userId);
		if(StringUtils.isNotNull(name)) {
			if(StringUtils.isNumeric(name)) {
				condition.put("processInstanceId", name);
			}else {
				condition.put("title", name);
			}
			
		}
		info.setCondition(condition);
		processInstanceEntityService.selectDataGrid(info);
		System.out.println(JsonUtil.toJson(info));
		return info;
	}
	/**
	 * 查询流程列表
	 * @param userId
	 * @param name
	 * @return
	 */
	@RequestMapping("/listWorkflow")
	@ResponseBody
	public Object listWorkflow(String userId,@RequestParam(value="name",required=false)String name) {
		if(StringUtils.isNotNull(name)) {
			return processTypeService.findByType(PROCESSTYPE_FLOW,name);
		}
		return processTypeService.findByType(PROCESSTYPE_FLOW);
	}
	
	/**
	 * 显示流程图,带流程跟踪
	 * 
	 * @param processInstanceId
	 * @param response
	 * @throws Exception
	 *
	 */
	@RequestMapping(value = "/showDiagram/{processInstanceId}", method = RequestMethod.GET)
	public void showDiagram(@PathVariable("processInstanceId") String processInstanceId, HttpServletResponse response)
			throws Exception {
		InputStream imageStream = this.activitiService.getDiagram(processInstanceId);
		// 输出资源内容到相应对象
		byte[] b = new byte[1024];
		int len;
		while ((len = imageStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	
	
	 /**
     * 查询当前流程图 待办用到的
     * @param processInstanceId
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/showHisCurrentView/{processInstanceId}")
    @ResponseBody
    public Map<String,Object> showHisCurrentView(@PathVariable("processInstanceId") String processInstanceId,HttpServletResponse response)throws Exception{
        Map<String,Object> map=new HashMap<String,Object>();
        HistoricProcessInstance hi=historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String processDefinitionId=hi.getProcessDefinitionId();
        ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery() // 创建流程定义查询
                .processDefinitionId(processDefinitionId) // 根据流程定义id查询
                .singleResult();
        map.put("deploymentId",processDefinition.getDeploymentId()); // 部署id
        map.put("diagramResourceName", processDefinition.getDiagramResourceName()); // 图片资源文件名称
        List<Task> tasks = activitiService.findByProcessInstanceId(processInstanceId);
        List<UserTask>userTasks=new ArrayList<UserTask>();
        for(int i=0;i<tasks.size();i++) {
        	UserTask userTask=new UserTask();
        	userTask.setTaskName(tasks.get(i).getName());
        	userTasks.add(userTask);
        }
        map.put("tasks", userTasks);
        log.info(JsonUtil.toJson(map));
        return map;
    }
    
    /**
     * 查看流程图
     * @param deploymentId
     * @param diagramResourceName
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/showView")
    public String showView(String deploymentId,String diagramResourceName,HttpServletResponse response)throws Exception{
        InputStream inputStream=repositoryService.getResourceAsStream(deploymentId, diagramResourceName);
        OutputStream out=response.getOutputStream();
        for(int b=-1;(b=inputStream.read())!=-1;){
            out.write(b);
        }
        out.close();
        inputStream.close();
        return null;
    }
    
	/**
	 * 显示图片通过部署id，不带流程跟踪(没有乱码问题)
	 * 
	 * @param processDefinitionId
	 * @param resourceType
	 *            资源类型(xml|image)
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/process-definition")
	public void loadByDeployment(@RequestParam("processDefinitionId") String processDefinitionId,
			@RequestParam("resourceType") String resourceType, HttpServletResponse response) throws Exception {
		InputStream resourceAsStream = this.activitiService.getDiagramByProDefinitionId_noTrace(resourceType,
				processDefinitionId);
		
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	/**
	 * 显示图片通过流程id，不带流程跟踪(没有乱码问题)
	 *
	 * @param resourceType
	 *            资源类型(xml|image)
	 * @param processInstanceId
	 *            流程实例ID
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/process-instance")
	public void loadByProcessInstance(@RequestParam("resourceType") String resourceType,
			@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse response)
			throws Exception {
		InputStream resourceAsStream = this.activitiService.getDiagramByProInstanceId_noTrace2(resourceType,
				processInstanceId);
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}
	
	
	/**
	 * 撤销任务
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/revoke")
	@ResponseBody
	public Object revoke(String taskId,String processInstanceId,String userId) throws Exception{
		Result result = new Result();
		try {
			User user=new User();
			user.setId(userId);
			Integer revokeFlag = this.activitiService.revoke(taskId, processInstanceId,user);
//			Integer revokeFlag = this.revokeTaskService.revoke(taskId, processInstanceId);
//			Command<Integer> cmd = new RevokeTask(taskId, processInstanceId);
//			Integer revokeFlag = this.processEngine.getManagementService().executeCommand(cmd);
			
			
			if(revokeFlag == 0){
				result.setSuccess(Boolean.TRUE);
				result.setMsg("撤销任务成功！");
			}else if(revokeFlag == 1){
				result.setSuccess(Boolean.FALSE);
				result.setMsg("撤销任务失败 - [ 此审批流程已结束! ]");
			}else if(revokeFlag == 2){
				result.setSuccess(Boolean.FALSE);
				result.setMsg("撤销任务失败 - [ 下一结点已经通过,不能撤销! ]");
			}
		} catch (Exception e) {
			result.setSuccess(Boolean.FALSE);
			result.setMsg("撤销任务失败 - [ 内部错误！]");
			throw e;
		}
		return result;
	}
}
